package com.googlecode.allinclusive.fw.web.struts2.interceptor;

import java.text.MessageFormat;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.apache.commons.lang.exception.ExceptionUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.struts2.ServletActionContext;

import com.googlecode.allinclusive.fw.web.valueobject.UserObject;
import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.config.entities.ExceptionMappingConfig;
import com.opensymphony.xwork2.interceptor.ExceptionHolder;
import com.opensymphony.xwork2.interceptor.ExceptionMappingInterceptor;

@Deprecated
public class CustomExceptionInterceptor extends ExceptionMappingInterceptor {

	/**
	 * serialVersionUID
	 */
	private static final long serialVersionUID = -4424896695197423200L;

	private static final Log log = LogFactory.getLog(CustomExceptionInterceptor.class);
	
	private static final MessageFormat MESSAGE_FORMAT = new MessageFormat("session:{0} user:{1} action:{2}#{3} [{4}]");
	
	public String intercept(ActionInvocation invocation) throws Exception {
		log.debug("exception interceptor.");
		try {
			return invocation.invoke();
		} catch (Exception ex) {
			
			log(invocation, ex);
            List<ExceptionMappingConfig> exceptionMappings = invocation.getProxy().getConfig().getExceptionMappings();
            String mappedResult = this.findResultFromExceptions(exceptionMappings, ex);
            if (mappedResult == null) {
            	throw ex;
            } else {
            	publishException(invocation, new ExceptionHolder(ex));
            	return mappedResult;
            }
		}
	}
	
	protected void log(ActionInvocation invocation, Exception ex) {
		ActionContext ac = invocation.getInvocationContext();
		HttpServletRequest request = (HttpServletRequest) ac.get(ServletActionContext.HTTP_REQUEST);
		HttpSession session = request.getSession();
		// Session ID
		final String sessionId = session.getId();
		// UserObject
		final UserObject userObject = (UserObject) session.getAttribute(UserObject.USER_OBJECT_KEY);
		final String userId;
		if (userObject != null) {
			userId = userObject.getUserId();
		} else {
			userId = null;
		}
		// Action
		final String actionName = invocation.getAction().getClass().getSimpleName();
		final String methodName = invocation.getProxy().getMethod();
		
		/*
		 * LINE 1 : session + user + action + Exception.getMessage();
		 * LINE 2 ~ LINE m : Request Object
		 * LINE m ~ LINE m+n : Session Object
		 * LINE m+n ~ LINE m+n+k : Exception Full StackTrace
		 */
		// TODO ???
		StringBuilder sb = new StringBuilder();
		sb.append(ex.getMessage());
		sb.append(Character.LINE_SEPARATOR);
		sb.append("HTTP RESUEST = ");
		sb.append(Character.LINE_SEPARATOR);
		sb.append("HTTP SESSION = ");
		sb.append(Character.LINE_SEPARATOR);
		sb.append("EXCEPTION = ");
		sb.append(ExceptionUtils.getFullStackTrace(ex));

		log.error(MESSAGE_FORMAT.format(new Object[]{sessionId, userId, actionName, methodName, sb.toString()}));
	}
}
